﻿using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using SevenZip;
using SevenZip.Compression;
using SevenZip.Compression.LZMA;
using System.Threading;
namespace GameCore {
    /// <summary>
    /// 文件工具
    /// </summary>
    public static class FileUtils
    {
        /// <summary>
        /// 拷贝文件
        /// </summary>
        public static void CopyFile(string inPath, string outPath) {
            try
            {
                string directoryPath = Path.GetDirectoryName(outPath);
                if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
                File.Copy(inPath, outPath, true);
            }
            catch (Exception e)
            {
                throw (e);
            }
        }
        /// <summary>
        /// 写入所有text
        /// </summary>
        public static void WriteAllText(string path, string text) {
            try
            {
                string directoryPath = Path.GetDirectoryName(path);
                if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
                File.WriteAllText(path, text);
            }
            catch (Exception e)
            {
                throw (e);
            }
        }
        /// <summary>
        /// 写入所有Bytes
        /// </summary>
        public static void WriteAllBytes(string path, byte[] bytes) {
            try {
                string directoryPath = Path.GetDirectoryName(path);
                if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
                File.WriteAllBytes(path, bytes);
            }
            catch (Exception e) {
                throw (e);
            }
        }
        /// <summary>
        /// 同步解压缩文件
        /// </summary>
        public static void DeCompress(string inFile, string outFile) {
            try
            {
                //判断是否存在源文件
                if (!File.Exists(inFile))throw (new Exception("SourceFile is not exits:" + inFile));
                //判断是否存在目标文件，如果存在，删除它
                if (File.Exists(outFile)) File.Delete(outFile);
                string directoryPath = Path.GetDirectoryName(outFile);
                if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
                Decoder coder = new Decoder();
                //已只读形式读取文件
                FileStream input = new FileStream(inFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                FileStream output = new FileStream(outFile, FileMode.Create);

                // Read the decoder properties
                byte[] properties = new byte[5];
                input.Read(properties, 0, 5);

                // Read in the decompress file size.
                byte[] fileLengthBytes = new byte[8];
                input.Read(fileLengthBytes, 0, 8);
                long fileLength = BitConverter.ToInt64(fileLengthBytes, 0);

                // Decompress the file.
                coder.SetDecoderProperties(properties);
                coder.Code(input, output, input.Length, fileLength, null);
                output.Flush();
                output.Close();
                input.Close();
            }
            catch (Exception e)
            {
                throw (e);
            }
        }

        /// <summary>
        /// 异步解压缩文件
        /// </summary>
        public static CodeProgress DeCompressAsync(string inFile, string outFile) {
            try
            {
                //判断是否存在源文件
                if (!File.Exists(inFile)) throw (new Exception("SourceFile is not exits:" + inFile));
                //判断是否存在目标文件，如果存在，删除它
                if (File.Exists(outFile)) File.Delete(outFile);
                string directoryPath = Path.GetDirectoryName(outFile);
                if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
                CodeProgress codeProgress = new CodeProgress();
                ThreadPool.QueueUserWorkItem((obj) =>
                {
                    Decoder coder = new Decoder();
                    //以只读形式读取文件，防止在IOS上报错
                    FileStream input = new FileStream(inFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                    FileStream output = new FileStream(outFile, FileMode.Create);

                    // Read the decoder properties
                    byte[] properties = new byte[5];
                    input.Read(properties, 0, 5);

                    // Read in the decompress file size.
                    byte[] fileLengthBytes = new byte[8];
                    input.Read(fileLengthBytes, 0, 8);
                    long fileLength = BitConverter.ToInt64(fileLengthBytes, 0);

                    // Decompress the file.
                    coder.SetDecoderProperties(properties);
                    coder.Code(input, output, input.Length, fileLength, codeProgress);
                    codeProgress.IsDone = true;
                    output.Flush();
                    output.Close();
                    input.Close();
                });
                return codeProgress;
            }
            catch (Exception e)
            {
                throw (e);
            }
        }



        /// <summary>
        /// 压缩文件
        /// </summary>
        public static void Compress(string inFile, string outFile) {
            try
            {
                //判断是否存在源文件
                if (!File.Exists(inFile)) throw (new Exception("SourceFile is not exits:" + inFile));
                //判断是否存在目标文件，如果存在，删除它
                if (File.Exists(outFile)) File.Delete(outFile);
                string directoryPath = Path.GetDirectoryName(outFile);
                if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
                Encoder coder = new Encoder();
                FileStream input = new FileStream(inFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                FileStream output = new FileStream(outFile, FileMode.Create);

                // Write the encoder properties
                coder.WriteCoderProperties(output);

                // Write the decompressed file size.
                output.Write(BitConverter.GetBytes(input.Length), 0, 8);

                // Encode the file.
                coder.Code(input, output, input.Length, -1, null);
                output.Flush();
                output.Close();
                input.Close();
            }
            catch (Exception e)
            {
                throw (e);
            }
        }

		/// <summary>
		/// 异步压缩文件
		/// </summary>
		public static CodeProgress CompressAsync(string inFile, string outFile) {
            
            try
			{
                CodeProgress codeProgress = new CodeProgress();
                //判断是否存在源文件
                if (!File.Exists(inFile)) throw (new Exception("SourceFile is not exits:" + inFile));
                //判断是否存在目标文件，如果存在，删除它
                if (File.Exists(outFile)) File.Delete(outFile);
                string directoryPath = Path.GetDirectoryName(outFile);
				if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
                ThreadPool.QueueUserWorkItem((obj) => {
                    Encoder coder = new Encoder();
                    FileStream input = new FileStream(inFile, FileMode.Open, FileAccess.Read, FileShare.Read);
                    FileStream output = new FileStream(outFile, FileMode.Create);

                    // Write the encoder properties
                    coder.WriteCoderProperties(output);

                    // Write the decompressed file size.
                    output.Write(BitConverter.GetBytes(input.Length), 0, 8);

                    // Encode the file.
                    coder.Code(input, output, input.Length, -1, codeProgress);
                    codeProgress.IsDone = true;
                    output.Flush();
                    output.Close();
                    input.Close();
                });
                return codeProgress;
            }
			catch (Exception e)
			{
				throw (e);
			}
		}

        public static void Delete(string v)
        {
            if (File.Exists(v))
                File.Delete(v);
        }
    }


    /// <summary>
    /// 进度
    /// </summary>
    public class CodeProgress : ICodeProgress
    {
        public void SetProgress(long inSize, long outSize)
        {
        }

        public bool IsDone
        {
            get;
            set;
        }
    }

}
